package com.ct.application.shipping.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ct.application.commons.vo.StatusRequest;
import com.ct.application.shipping.model.po.LiChuanShenQingSavePO;
import com.ct.application.shipping.model.po.LiChuanShenQingSearchPO;
import com.ct.application.shipping.model.po.LiuChengDingYiBuZhouSavePO;
import com.ct.application.shipping.model.po.LiuChengYeWuSavePO;
import com.ct.application.shipping.model.vo.LiChuanShenQingVO;
import com.ct.application.shipping.service.*;
import com.ct.repository.commons.BaseServiceImpl;
import com.ct.shipping.mapper.LiChuanShenQingMapper;
import com.ct.shipping.orm.*;
import com.ct.utils.date.DateUtils;
import com.ct.utils.date.TmDateUtil;
import com.ct.utils.threadlocal.UserThreadLocal;
import com.ct.utils.valid.ValidatorUtil;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 离船申请 服务实现类
 * </p>
 *
 * @author carlo
 */
@Service
public class LiChuanShenQingServiceImpl extends BaseServiceImpl<LiChuanShenQingMapper, LiChuanShenQingDO>
        implements LiChuanShenQingService {

    @Resource
    private ChuanYuanKuService chuanYuanKuService;
    @Resource
    private ShenPiDanHaoService shenPiDanHaoService;
    @Resource
    private LiuChengDingYiService liuChengDingYiService;
    @Resource
    private LiuChengYeWuService liuChengYeWuService;
    @Resource
    private ChuanYuanDiaoPeiService chuanYuanDiaoPeiService;




    /**
     * 查询分页列表
     */
    @Override
    public Page<LiChuanShenQingVO> findLiChuanShenQing(LiChuanShenQingSearchPO searchPO) {
        LambdaQueryWrapper<LiChuanShenQingDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.eq(!("全选".equals(searchPO.getChuanBoMing())), LiChuanShenQingDO::getSuoZaiChuanBo, searchPO.getChuanBoMing())
                .eq(!("全选".equals(searchPO.getZhiWei())), LiChuanShenQingDO::getZhiWei, searchPO.getZhiWei())
                .eq(!("全选".equals(searchPO.getShenPiZhuangTai())), LiChuanShenQingDO::getShenPiZhuangTai, searchPO.getShenPiZhuangTai());

        if(StringUtils.isNotEmpty(searchPO.getKeyword())){
            lambdaQueryWrapper.and(w->{
                w.like(LiChuanShenQingDO::getChuanYuanMing,searchPO.getKeyword())
                        .or()
                        .like(LiChuanShenQingDO::getLiChuanYuanYin,searchPO.getKeyword());
            });
        }
        if (StringUtils.isNotEmpty(searchPO.getStartDate()) && StringUtils.isNotEmpty(searchPO.getEndDate())) {
            lambdaQueryWrapper.ge(LiChuanShenQingDO::getShengQingRiQi, DateUtils.stringToDate(searchPO.getStartDate()))
                    .le(LiChuanShenQingDO::getShengQingRiQi, DateUtils.stringToDate(searchPO.getEndDate()));
        }
        lambdaQueryWrapper.orderByDesc(LiChuanShenQingDO::getCreateTime);
        Page<LiChuanShenQingDO> page = new Page<>(searchPO.getPageNo(), searchPO.getPageSize());
        Page<LiChuanShenQingDO> page1 = this.page(page, lambdaQueryWrapper);
        return tranferPageBo(page1, LiChuanShenQingVO.class);
    }


    /**
     * 保存
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveLiChuanShenQing(LiChuanShenQingSavePO savePO){
        savePO.setId(null); //新增不需要id
        //有接替人员
        Long chuanYuanId = savePO.getChuanYuanId();
        ChuanYuanKuDO chuanYuanDO = chuanYuanKuService.getById(chuanYuanId);
        if (chuanYuanDO == null) {
            throw new RuntimeException("查无此船员数据");
        }
        Date currentDate = DateUtils.stringToDate(DateUtils.format(new Date()));
        Date xiaChuanKaiShiRiQi = DateUtils.stringToDate(savePO.getXiaChuanKaiShiRiQi());
        Date xiaChuanJieShuRiQi = DateUtils.stringToDate(savePO.getXiaChuanJieShuRiQi());

        if (xiaChuanKaiShiRiQi.before(currentDate) || xiaChuanJieShuRiQi.before(currentDate) ) {
            throw new RuntimeException("下船日期不能在今天之前");
        }

        LiChuanShenQingDO liChuanShenQingDO = tranferBo(savePO, LiChuanShenQingDO.class);
        if (Objects.nonNull(liChuanShenQingDO)){
            LocalDate shangChuanDate = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            int nian = shangChuanDate.getYear();
            int yue = shangChuanDate.getMonthValue();
            ShenPiDanHaoDO danHaoDO = shenPiDanHaoService.lambdaQuery()
                    .eq(ShenPiDanHaoDO::getNian, String.valueOf(nian))
                    .eq(ShenPiDanHaoDO::getYue, String.valueOf(yue))
                    .eq(ShenPiDanHaoDO::getLeiXing, "申请单")
                    .last(" limit 1 ")
                    .one();
            if (danHaoDO != null) {
                long xinHaoMa = danHaoDO.getHaoMa() + 1;
                liChuanShenQingDO.setShenQingDanHao(nian + "" + String.format("%02d", yue) + "" + String.format("%04d", xinHaoMa));

                ShenPiDanHaoDO danHaoUpdate = new ShenPiDanHaoDO();
                danHaoUpdate.setId(danHaoDO.getId());
                danHaoUpdate.setHaoMa(xinHaoMa);
                danHaoUpdate.updateById();
            } else {
                danHaoDO = new ShenPiDanHaoDO();
                danHaoDO.setNian(String.valueOf(nian));
                danHaoDO.setYue(String.valueOf(yue));
                danHaoDO.setHaoMa(1L);
                danHaoDO.setLeiXing("申请单");
                danHaoDO.insert();
                liChuanShenQingDO.setShenQingDanHao(nian + "" + String.format("%02d", yue) + "" + "0001");
            }
            //liChuanShenQingDO.setCreateBy(UserThreadLocal.get().getUsername());
            liChuanShenQingDO.setChuanYuanId(chuanYuanDO.getId());
            liChuanShenQingDO.setChuanYuanMing(chuanYuanDO.getXingMing());
            liChuanShenQingDO.setShengQingRiQi(new Date());
            liChuanShenQingDO.setShenPiZhuangTai("审批中");
            liChuanShenQingDO.setSystemId(UserThreadLocal.get().getSystemId());
            liChuanShenQingDO.setSystemName(UserThreadLocal.get().getSystemName());
            boolean save = this.save(liChuanShenQingDO);
            if (save) {
                LiuChengDingYiDO liuChengDingYiDO = liuChengDingYiService.lambdaQuery()
                        .eq(LiuChengDingYiDO::getLiuChengLeiXing, "离船申请")
                        .like(LiuChengDingYiDO::getChuanBoMing, liChuanShenQingDO.getSuoZaiChuanBo())
                        .like(LiuChengDingYiDO::getZhiWeiMing, liChuanShenQingDO.getZhiWei())
                        .orderByDesc(LiuChengDingYiDO::getId)
                        .last(" limit 1 ").one();
                if (liuChengDingYiDO == null) {
                    liuChengDingYiDO = liuChengDingYiService.lambdaQuery()
                            .eq(LiuChengDingYiDO::getLiuChengLeiXing, "离船申请")
                            .eq(LiuChengDingYiDO::getChuanBoMing, "全部")
                            .eq(LiuChengDingYiDO::getZhiWeiMing, "全部")
                            .orderByDesc(LiuChengDingYiDO::getId)
                            .last(" limit 1 ").one();
                    if (liuChengDingYiDO == null) {
                        throw new RuntimeException("所选的船舶和职位找不到匹配的流程，无法发起流程");
                    }
                }
                //流程步骤对象数据
                String buZhouShuJu = liuChengDingYiDO.getBuZhouShuJu();
                List<LiuChengDingYiBuZhouSavePO> buZhouList = JSONArray.parseArray(buZhouShuJu, LiuChengDingYiBuZhouSavePO.class);
                for (int i = 0; i < buZhouList.size(); i++) {
                    LiuChengDingYiBuZhouSavePO buZhou = buZhouList.get(i);
                    LiuChengYeWuDO liuChengYeWuDO = new LiuChengYeWuDO();
                    liuChengYeWuDO.setLiuChengLeiXing("离船申请");
                    liuChengYeWuDO.setYeWuId(liChuanShenQingDO.getId());
                    liuChengYeWuDO.setLiuChengDingYiId(liuChengDingYiDO.getId());
                    liuChengYeWuDO.setJueSeId(buZhou.getJueSeId());
                    liuChengYeWuDO.setJueSeMing(buZhou.getJueSeMing());
                    liuChengYeWuDO.setJieDianMing(buZhou.getJieDianMing());
                    liuChengYeWuDO.setJieDianCaoZuo("");
                    liuChengYeWuDO.setShenPiYiJian("");
                    liuChengYeWuDO.setShiFouShenPi("否");
                    liuChengYeWuDO.setShenPiZhuangTai("审批中");
                    liuChengYeWuDO.setShiFouZuiHouJieDian("否");
                    if (i == (buZhouList.size() - 1)) {
                        liuChengYeWuDO.setShiFouZuiHouJieDian("是");
                    }
                    liuChengYeWuDO.insert();
                }

                /*找到船员调配的数据，设置离船申请参数*/
                ChuanYuanDiaoPeiDO chuanYuanDiaoPeiDO = chuanYuanDiaoPeiService.lambdaQuery()
                        .eq(ChuanYuanDiaoPeiDO::getChuanBoMing, liChuanShenQingDO.getSuoZaiChuanBo())
                        .eq(ChuanYuanDiaoPeiDO::getZhiWei, liChuanShenQingDO.getZhiWei())
                        .eq(ChuanYuanDiaoPeiDO::getZaiChuanChuanYuanId, liChuanShenQingDO.getChuanYuanId())
                        .last(" limit 1 ")
                        .one();
                if (chuanYuanDiaoPeiDO != null) {
                    chuanYuanDiaoPeiService.lambdaUpdate()
                            .set(ChuanYuanDiaoPeiDO::getLiChuanShenQingCanShu, JSONObject.toJSONString(liChuanShenQingDO))
                            .eq(ChuanYuanDiaoPeiDO::getId,chuanYuanDiaoPeiDO.getId())
                            .update();
                }
            }
        }
        return true;
    }


    @Override
    public LiChuanShenQingVO getLiChuanShenQing(Long id){
        LiChuanShenQingDO liChuanShenQingDO = getById(id);
        LiChuanShenQingVO liChuanShenQingVO = tranferBo(liChuanShenQingDO, LiChuanShenQingVO.class);
        List<LiuChengYeWuDO> liuChengYeWuList = liuChengYeWuService.lambdaQuery()
                .eq(LiuChengYeWuDO::getLiuChengLeiXing, "离船申请")
                .eq(LiuChengYeWuDO::getYeWuId, id)
                .list();
        liChuanShenQingVO.setLiuChengYeWuList(liuChengYeWuList);
        return liChuanShenQingVO;
    }

    /**
     * 流程审批操作
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean shenPi(LiuChengYeWuSavePO savePO){
        Long id = savePO.getId();
        if (id == null) {
            throw new RuntimeException("id不能为空");
        }
        if (savePO.getJieDianCaoZuo().equals("同意") || savePO.getJieDianCaoZuo().equals("拒绝")) {
        } else {
            throw new RuntimeException("节点操作参数值只能是`同意`或`拒绝`");
        }
        LiuChengYeWuDO liuChengYeWuDO = liuChengYeWuService.getById(id);
        if (liuChengYeWuDO == null) {
            throw new RuntimeException("流程对象数据不能为空");
        }
        if ("是".equals(liuChengYeWuDO.getShiFouShenPi())) {
            throw new RuntimeException("该节点已有人审批，请刷新数据查看");
        }

        LiuChengYeWuDO liuChengYeWuDOUpdate = new LiuChengYeWuDO();
        liuChengYeWuDOUpdate.setId(id);
        liuChengYeWuDOUpdate.setShenPiRen(UserThreadLocal.get().getUsername());
        liuChengYeWuDOUpdate.setJieDianCaoZuo(savePO.getJieDianCaoZuo());   //节点操作。 同意/拒绝
        liuChengYeWuDOUpdate.setShenPiYiJian(savePO.getShenPiYiJian());     //审批意见
        liuChengYeWuDOUpdate.setShiFouShenPi("是");                         //该节点是否已有人审批
        if ("同意".equals(savePO.getJieDianCaoZuo()) && "是".equals(liuChengYeWuDO.getShiFouZuiHouJieDian())) {
            //离船申请数据修改状态
            this.lambdaUpdate()
                    .set(LiChuanShenQingDO::getShenPiZhuangTai,"审批通过")
                    .eq(LiChuanShenQingDO::getId,liuChengYeWuDO.getYeWuId())
                    .update();
            liuChengYeWuDOUpdate.updateById();
            liuChengYeWuService.lambdaUpdate()
                    .set(LiuChengYeWuDO::getShenPiZhuangTai,"审批通过")
                    .eq(LiuChengYeWuDO::getYeWuId,liuChengYeWuDO.getYeWuId())
                    .update();
        }
        if ("拒绝".equals(savePO.getJieDianCaoZuo())) {
            //离船申请数据修改状态
            this.lambdaUpdate()
                    .set(LiChuanShenQingDO::getShenPiZhuangTai,"审批拒绝")
                    .eq(LiChuanShenQingDO::getId,liuChengYeWuDO.getYeWuId())
                    .update();
            liuChengYeWuDOUpdate.updateById();
            liuChengYeWuService.lambdaUpdate()
                    .set(LiuChengYeWuDO::getShenPiZhuangTai,"审批拒绝")
                    .eq(LiuChengYeWuDO::getYeWuId,liuChengYeWuDO.getYeWuId())
                    .update();
        }
        return true;
    }







}
